package pkg.andru.animation;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * </p> <b>for the design, the anime, frame, and sprite must in the 'res/xml'
 * folder, and the frame define file must be the 'frames.xml' and sprites must
 * be 'sprites.xml', so the name define like follow:
 * <p>
 * res/xml/sprites.xml <br>
 * res/xml/frames.xml <br>
 * res/xml/anime1.xml <br>
 * res/xml/anime2.xml<br>
 * ...
 * <p>
 * 
 * for make a diff with the system view's animation method, all method add a
 * 'F', like {@link #setFAnime(int)} and {@link #setFAnimeLoop(boolean)}, etc...
 * 
 * @author idiottiger
 * 
 */
public class AnimeView extends View {

    static final String TAG = "AnimeView";

    private boolean isLoop;

    private AnimeParser mParser;
    private Anime mAnime;
    private AnimeDrawState mDrawState;

    public AnimeView(Context context) {
        this(context, null);
    }

    public AnimeView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AnimeView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mParser = new AnimeParser(context);
    }

    /**
     * set the anime loop or not
     * 
     * @param loop
     */
    public void setFAnimeLoop(boolean loop) {
        isLoop = loop;
    }

    public void startFAnime() {
        startFAnime(0);
    }

    public void startFAnime(int delay) {
        if (mDrawState != null) {
            mDrawState.startAnime(delay);
        }
    }

    public void stopFAnime() {
        if (mDrawState != null) {
            mDrawState.stopAnime();
        }
    }

    public void releaseFAnime() {
        mDrawState = null;
    }

    /**
     * parase anime with giving anmId, framesId, spritesId, this three ids must
     * be in 'res/xml' folder
     * 
     * @param animId
     * @param framesId
     * @param spritesId
     * @throws AnimeParseException
     *             when parse error will throw
     */
    public void parseAnime(int animId, int framesId, int spritesId) throws AnimeParseException {
        mAnime = mParser.parseAnime(animId, framesId, spritesId);
        if (mAnime != null) {
            mDrawState = new AnimeDrawState() {
                @Override
                public void animeUpdate() {
                    invalidate();
                }
            };
            mDrawState.bindAnime(mAnime);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mAnime != null && mDrawState != null) {
            mDrawState.setLoop(isLoop);
            Log.i(TAG, "anime view on draw");
            mAnime.onDraw(canvas, mDrawState);
        }
    }

}
